package com.eye.catcher.controller;


import com.alibaba.fastjson.JSONObject;
import com.eye.catcher.param.CommonResponse;
import com.eye.catcher.constants.RedisConstants;
import com.eye.catcher.constants.SbCode;
import com.eye.catcher.entity.TSysDaUser;
import com.eye.catcher.param.ResponseData;
import com.eye.catcher.param.ResponseUtil;
import com.eye.catcher.rabbit.MQDto;
import com.eye.catcher.service.generate.ITSysDaUserRoleService;
import com.eye.catcher.service.generate.ITSysDaUserService;
import com.eye.catcher.system.user.param.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author huzhiwei
 * @since 2022-02-08
 */
@Slf4j
@Controller
@RequestMapping("/eyeCatcher-system/sys-user")
public class TSysDaUserController extends TSysDaBaseController {
    private final static String MODULE_CODE = "/sys-user";
    private final static String MODULE_NAME = "用户";

    @Autowired
    private ITSysDaUserService userService;
    @Autowired
    private ITSysDaUserRoleService userRoleService;
    /**
     * 登陆
     * @author huzhiwei
     * @since 2022-02-08
     * @param requst
     * @return
     */
    @PostMapping("/login")
    @ResponseBody
    public ResponseData login(@RequestBody UserLoginRequst requst) {
        String methodCode = "/login";
        UserLoginResponse response = null;
        if (requst.getUsername().equals("")) {
            return new ResponseUtil().setErrorMsg("用户名不能为空");
        }
        if (requst.getPassword().equals("")) {
            return new ResponseUtil().setErrorMsg("密码不能为空");
        }
        try {
            response = userService.login(requst);
            if(!SbCode.SUCCESS.getCode().equals(response.getCode())){
                return new ResponseUtil().setErrorMsg("用户名或密码错误");
            }
            //清空 用户数据缓存
            String key = RedisConstants.USER_INFO_EXPIRE.getKey()+response.getUserId();
            redisUtils.del(key);
            redisUtils.del(key+SbCode.GETUSERINFOBYID_TYPE_All.getCode());
            redisUtils.del(key+SbCode.GETUSERINFOBYID_TYPE_NOT_MODULE.getCode());
            redisUtils.del(key+SbCode.GETUSERINFOBYID_TYPE_ONLAY_MODULE.getCode());
            //刷一下用户信息
            this.getUserInfo(response.getUserId(),null,"N");
            log.info(methodCode + response.toString());
            return new ResponseUtil().setData(response);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
            return new ResponseUtil().setData(commonResponse);
        } finally {
            //发送登录日志 mq
            if(!SbCode.SUCCESS.getCode().equals(response.getCode())){//登陆失败
                this.sendLoginRabbitMqLog(methodCode,requst.toString(),
                        MODULE_CODE,MODULE_NAME,this.getClass().getName(),
                        null == commonResponse?null:commonResponse.toString(),null,requst.getUsername());
            }else{
                this.sendLoginRabbitMqLog(methodCode,requst.toString(),
                        MODULE_CODE,MODULE_NAME,this.getClass().getName(),
                        null == commonResponse?null:response.toString(),response.getUserId(),requst.getUsername());
            }

        }
    }

    /**
     * @author huzhiwei
     * @since 2022-02-08
     * 获取用户信息接口
     * @return
     */
    @PostMapping("/getUserInfo")
    @ResponseBody
    public ResponseData getUserInfo(@RequestParam(value = "userId", defaultValue = "") String userId,
                                    @RequestParam(value = "getUserInfoType", defaultValue = "") String getUserInfoType,
                                    @RequestParam(value = "cacheType", defaultValue = "") String cacheType) {
        String methodCode = "/getUserInfo";
        UserLoginInfo userLoginInfo = null;
        if(StringUtils.isEmpty(userId)){
            userId = getLoginUserId();
        }
        if(StringUtils.isEmpty(getUserInfoType)){
            getUserInfoType = SbCode.GETUSERINFOBYID_TYPE_All.getCode();
        }
        try {
            String key = RedisConstants.USER_INFO_EXPIRE.getKey()+userId;
            if(!SbCode.GETUSERINFOBYID_TYPE_All.getCode().equals(getUserInfoType)){
                key += getUserInfoType;
            }
            if(!"N".equals(cacheType)) {
                if (redisUtils.hasKey(key)) {
                    log.info(methodCode + "->redis\n");
                    userLoginInfo = (UserLoginInfo) redisUtils.get(key);
                    return new ResponseUtil<>().setData(userLoginInfo);
                }
            }
            userLoginInfo = userService.getUserInfoById(userId,getUserInfoType);
            if(SbCode.SUCCESS.getCode().equals(userLoginInfo.getCode())){
                redisUtils.set(key, userLoginInfo, RedisConstants.USER_INFO_EXPIRE.getTime());
            }
            log.info(methodCode+"\n");
            return new ResponseUtil<>().setData(userLoginInfo);
        } catch (Exception e) {
            log.error(methodCode+"\n", e);
            commonResponse = CommonResponse.error();
            return new ResponseUtil().setData(commonResponse);
        }finally {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("userId",userId);
            jsonObject.put("getUserInfoType",getUserInfoType);
            jsonObject.put("cacheType",cacheType);
            //发送登录日志 mq
            if(!SbCode.SUCCESS.getCode().equals(userLoginInfo.getCode())){//登陆失败
                this.sendLoginRabbitMqLog(methodCode,jsonObject.toString(),
                        MODULE_CODE,MODULE_NAME,this.getClass().getName(),
                        null == commonResponse?null:commonResponse.toString(),userId,null);
            }else{
                this.sendLoginRabbitMqLog(methodCode,jsonObject.toString(),
                        MODULE_CODE,MODULE_NAME,this.getClass().getName(),
                        null == commonResponse?null:userLoginInfo.toString(),
                        userId,userLoginInfo.getUserDto().getLoginName());
            }

        }
    }

    /**
     * @author huzhiwei
     * @since 2022-02-08
     * @param user
     * @return
     */
    @PostMapping("/addUser")
    @ResponseBody
    public ResponseData addUser(@RequestBody TSysDaUser user) {
        String methodCode = "/addUser";
        MQDto mqDto = null;
        try{
            String userId  = getLoginUserId();
            mqDto = new MQDto(methodCode,userId,MODULE_CODE,MODULE_NAME,getClass(),
                    SbCode.OPERATION_ADD,user.toString(),null,null);
            this.sendInitRabbitMqLog(mqDto);
            this.userService.addUser(user,userId);
            commonResponse = CommonResponse.success();
            log.info(methodCode, commonResponse.toString());
        }catch (Exception e){
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
            return new ResponseUtil().setData(commonResponse);
        }finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }
    /**
     * @author huzhiwei
     * @since 2022-02-08
     * @param user
     * @return
     */
    @PostMapping("/editUser")
    @ResponseBody
    public ResponseData editUser(@RequestBody TSysDaUser user) {
        String methodCode = "/editUser";
        MQDto mqDto = null;
        try{
            String userId  = getLoginUserId();
            mqDto = new MQDto(methodCode,userId,MODULE_CODE,MODULE_NAME,getClass(),
                    SbCode.OPERATION_ADD,user.toString(),null,null);
            this.sendInitRabbitMqLog(mqDto);
            this.userService.editUser(user,userId);
            commonResponse = CommonResponse.success();
            log.info(methodCode, commonResponse.toString());
        }catch (Exception e){
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
            return new ResponseUtil().setData(commonResponse);
        }finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }

    /**
     * @author huzhiwei
     * @since 2022-02-08
     * @param userIds
     * @param password
     * @return
     */
    @PostMapping("/editBatchUserPassword")
    @ResponseBody
    public ResponseData editBatchUserPassword(@RequestParam(value = "userIds") String userIds,
                                         @RequestParam(value = "password") String password) {
        String methodCode = "/editBatchUserPassword";
        MQDto mqDto = null;
        try{
            String userId  = getLoginUserId();
            mqDto = new MQDto(methodCode,userId,MODULE_CODE,MODULE_NAME,getClass(),
                    SbCode.OPERATION_ADD,"userIds:"+userIds+";password:"+password,null,null);
            this.sendInitRabbitMqLog(mqDto);
            this.userService.editUserPassword(userIds,password,userId);
            commonResponse = CommonResponse.success();
            log.info(methodCode, commonResponse.toString());
        }catch (Exception e){
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
            return new ResponseUtil().setData(commonResponse);
        }finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }

    /**
     * @author huzhiwei
     * @since 2022-02-08
     * @param userIds
     * @return
     */
    @PostMapping("/deleteUserByIds")
    @ResponseBody
    public ResponseData deleteUserByIds(@RequestParam(value = "userIds") String userIds) {
        String methodCode = "/deleteUserByIds";
        MQDto mqDto = null;
        try{
            mqDto = new MQDto(methodCode,getLoginUserId(),MODULE_CODE,MODULE_NAME,getClass(),
                    SbCode.OPERATION_EDIT,"ids："+userIds,null,null);
            this.sendInitRabbitMqLog(mqDto);
            this.userService.deleteUserByIds(userIds);
            this.userRoleService.deleteUserRoleByUserIds(userIds,null);
            commonResponse = CommonResponse.success();
            log.info(methodCode, commonResponse.toString());
        }catch (Exception e){
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
            return new ResponseUtil().setData(commonResponse);
        }finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }

    @PostMapping("/updateStausByIds")
    @ResponseBody
    public ResponseData updateStausByIds(@RequestParam(value = "ids") String ids) {
        String methodCode = "/updateStausByIds";
        MQDto mqDto = null;
        try{
            mqDto = new MQDto(methodCode,getLoginUserId(),MODULE_CODE,MODULE_NAME,getClass(),
                    SbCode.OPERATION_EDIT,"ids:"+ids,null,null);
            this.sendInitRabbitMqLog(mqDto);
            this.userService.updateStausByIds(ids);
            commonResponse = CommonResponse.success();
            log.info(methodCode, commonResponse.toString());
        }catch (Exception e){
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
        }finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }

    /**
     * @author huzhiwei
     * @since 2022-02-08
     * @param user
     * @return
     */
    @PostMapping("/getUserList")
    @ResponseBody
    public ResponseData getUserList(@RequestBody UserDto user) {
        String methodCode = "/getUserList";
        MQDto mqDto = null;
        try{
            mqDto = new MQDto(methodCode,getLoginUserId(),MODULE_CODE,MODULE_NAME,
                    getClass(),SbCode.OPERATION_QUERY,user.toString(),null,null);
            this.sendInitRabbitMqLog(mqDto);
            commonResponse = CommonResponse.success();
            commonResponse.setData(
                    this.userService.getPageUserList(
                            UserPage.builder()
                                    .user(user)
                                    .page(this.getPageInfo(user))
                                    .build()
                    )
            );
            log.info(methodCode, commonResponse.toString());
        }catch (Exception e){
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
            return new ResponseUtil().setData(commonResponse);
        }finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }

    /**
     * 导出模板
     */
    @RequestMapping(path = "/exportUserTemplate")
    public @ResponseBody
    ResponseData exportUserTemplate(HttpServletRequest request, HttpServletResponse response) {
        String methodCode = "/exportUserTemplate";
        MQDto mqDto = null;
        try{
            mqDto = new MQDto(methodCode, getLoginUserId(), MODULE_CODE, MODULE_NAME, getClass(),
                    SbCode.OPERATION_DOWLOAD, null, null, null);
            this.sendInitRabbitMqLog(mqDto);
            String msg = this.userService.exportUserTemplate(request,response);
            if (StringUtils.isNotEmpty(msg)) {
                commonResponse = CommonResponse.getInstance();
                commonResponse.setCode(SbCode.SYSTEM_ERROR.getCode());
                commonResponse.setMsg(msg);
                commonResponse.setData(null);
            } else {
                commonResponse = CommonResponse.success();
            }
        } catch (Exception e) {
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
        } finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }

    /**
     * 导入
     */
    @RequestMapping(path = "/uploadUserTemplate")
    public @ResponseBody
    ResponseData uploadUserTemplate(@RequestParam("file") MultipartFile file) {
        String methodCode = "/uploadUserTemplate";
        MQDto mqDto = null;
        try{
            String userId = getLoginUserId();
            mqDto = new MQDto(methodCode,userId,MODULE_CODE,MODULE_NAME,getClass(),
                    SbCode.OPERATION_UPLOAD,null,null,null);
            this.sendInitRabbitMqLog(mqDto);
            String msg = this.userService.uploadUserTemplate(file,userId);
            if (StringUtils.isNotEmpty(msg)) {
                commonResponse = CommonResponse.getInstance();
                commonResponse.setCode(SbCode.SYSTEM_ERROR.getCode());
                commonResponse.setMsg(msg);
                commonResponse.setData(null);
            } else {
                commonResponse = CommonResponse.success();
            }
        } catch (Exception e) {
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
        } finally {
            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }

}
